package utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;

import datensaetze.Datensatz;
import de.dnb.music.publicInterface.MusicRecord;
import de.dnb.music.publicInterface.TransformRecord;
import de.dnb.music.publicInterface.TransformRecord.TransformMode;
import exceptions.NoPreferredNameException;
import exceptions.NoSuchItemException;

public abstract class TransformerTemplate {

	protected DownloadBearbeiter bearbeiter = new DownloadBearbeiter() {

		@Override
		public void bearbeiteDS(Datensatz ds) {
			String rawData = ds.getRohdaten();
			String idn = ds.getIdn();

			rawData = removeExpansions(rawData);

			String newData = processData(rawData);
			
			newData = sortData(newData);
			
			/*
			 * Daten werden nicht abgespeichert, wenn
			 * 	- keine Änderung erfogte
			 * 	- finalAccept() nicht akzeptiert.
			 */
			if (!isIdentical(rawData, newData)
				&& finalAccept(newData, rawData)) {
				newData = addIdn(newData, idn);
				newData = sortData(newData);
				save(newData);
			} else {
				log(rawData);
			}
		}

	};
	private File inputFile;

	// Default-Werte
	private PrintStream out = System.out;
	private String recordSeparator = "\n\t\n\n";

	public final void setRecordSeparator(final String recordSeparator) {
		this.recordSeparator = recordSeparator;
	}

	protected void log(String rawData) {
		System.err.println(rawData + "\n\n---\n\n");
	}

	protected abstract boolean isIdentical(String rawData, String newData);

	protected String addIdn(final String rawData, final String idn) {
		return rawData + "\n797 " + idn;
	}

	protected String transform2PicaPlus(final String rawData) {
		return StringUtils.gnd2Pica(rawData);
	}

	protected final String sortData(final String rawData) {
		return StringUtils.sortFields(rawData);
	}

	public final void work() {
		try {
			bearbeiter.bearbeiteFile(inputFile, "UTF-8");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoPreferredNameException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchItemException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public final void setInputFile(final File file) {
		this.inputFile = file;
	}

	public final void setInputFile(final String file) {
		this.inputFile = new File(file);
	}

	public final void setOutputFile(final File file) {
		try {
			this.out = new PrintStream(file, "UTF-8");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * @param file the outputFile to set
	 */
	public final void setOutputFile(final String file) {
		try {
			this.out = new PrintStream(file);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	final void save(final String rawData) {
		this.out.append(recordSeparator);
		this.out.append(rawData);

	}

	protected abstract String processData(String rawData);

	protected final String removeExpansions(final String rawData) {
		return StringUtils.removeExpansion(rawData);
	}

	final String replaceF(final String rawData) {
		return rawData.replace('ƒ', '$');
	}
	
	/**
	 * Wenn es noch Besonderheiten gibt, die das Einspielen der Daten
	 * verhindern sollen.
	 * 
	 * @param newData	nicht null.
	 * @param oldData TODO
	 * @return		ob der Datensatz akzeptiert wird.
	 */
	public boolean finalAccept(
			final String newData,
			final String oldData) {
		return true;
		
	}

}
